package tk.winshu.transaction.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.winshu.transaction.common.CustomException;

/**
 * https://juejin.im/entry/5a8fe57e5188255de201062b
 *
 * @author Kevin
 * @since 2019/04/06.
 */
@Service
public class GroupService {

    private final UserService userService;

    private final RoleService roleService;

    @Autowired
    public GroupService(UserService userService, RoleService roleService) {
        this.userService = userService;
        this.roleService = roleService;
    }

    private void throwCustomException() {
        throw new CustomException();
    }

    /**
     * 1
     * 条件：外部无事务，且抛出异常
     * 结果：User 提交，Role 提交
     * 数据：user_1,role_1
     */
    public void testNoTransactionExceptionRequiredRequired() {
        userService.createWithRequired(1);
        roleService.createWithRequired(1);
        throwCustomException();
    }

    /**
     * 2
     * 条件：外部无事务，Role 异常
     * 结果：User 提交，Role 回滚
     * 数据：user_2
     */
    public void testNoTransactionRequiredRequiredException() {
        userService.createWithRequired(2);
        roleService.createWithRequiredException(2);
    }

    /**
     * 3
     * 条件：外部开启事务，且抛出异常
     * 结果：User 回滚，Role 回滚
     * 数据：无
     */
    @Transactional
    public void testTransactionExceptionRequiredRequired() {
        userService.createWithRequired(3);
        roleService.createWithRequired(3);
        throwCustomException();
    }

    /**
     * 4
     * 条件：外部开启事务，Role 异常
     * 结果：User 回滚，Role 回滚`
     * 数据：无
     */
    @Transactional
    public void testTransactionRequiredRequiredException() {
        userService.createWithRequired(4);
        roleService.createWithRequiredException(4);
    }

    /**
     * 5
     * 条件：外部开启事务，Role 异常，且被捕获
     * 结果：User 回滚，Role 回滚
     * 数据：无
     */
    @Transactional
    public void testTransactionRequiredRequiredExceptionTry() {
        userService.createWithRequired(5);
        try {
            roleService.createWithRequiredException(5);
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
    }

    /**
     * 6
     * 条件：外部无事务，且抛出异常
     * 结果：User 提交，Role 提交
     * 数据：user_6,role_6
     */
    public void testNoTransactionExceptionRequiredRequiresNew() {
        userService.createWithRequired(6);
        roleService.createWithRequiresNew(6);
        throwCustomException();
    }

    /**
     * 6
     * 条件：外部无事务，Role 抛出异常
     * 结果：User 提交，Role 回滚
     * 数据：user_7
     */
    public void testNoTransactionRequiredRequiresNewException() {
        userService.createWithRequired(7);
        roleService.createWithRequiresNewException(7);
    }

    /**
     * 8
     * 条件：外部开启事务，且抛出异常
     * 结果：User 回滚，Role1 提交，Role2 提交
     * 数据：role_8,role_80
     */
    @Transactional
    public void testTransactionExceptionRequiredRequiresNewRequiresNew() {
        userService.createWithRequired(8);
        roleService.createWithRequiresNew(8);
        roleService.createWithRequiresNew(80);
        throwCustomException();
    }

    /**
     * 9
     * 条件：外部开启事务，Role2 异常
     * 结果：User 回滚，Role1 提交，Role2 回滚
     * 数据：role_9
     */
    @Transactional
    public void testTransactionRequiredRequiresNewRequiresNewException() {
        userService.createWithRequired(9);
        roleService.createWithRequiresNew(9);
        roleService.createWithRequiresNewException(90);
    }

    /**
     * 10
     * 条件：外部开启事务，Role2 捕获异常
     * 结果：User 提交，Role1 提交，Role2 回滚
     * 数据：user_10,role_10
     */
    @Transactional
    public void testTransactionRequiredRequiresNewRequiresNewExceptionTry() {
        userService.createWithRequired(10);
        roleService.createWithRequiresNew(10);
        try {
            roleService.createWithRequiresNewException(100);
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
    }

    /**
     * 11
     * 条件：外部无事务，且抛出异常
     * 结果：User 提交，Role 提交
     * 数据：user_11,role_11
     */
    public void testNoTransactionExceptionNestedNested() {
        userService.createWithNested(11);
        roleService.createWithNested(11);
        throwCustomException();
    }

    /**
     * 12
     * 条件：外部无事务，Role 抛出异常
     * 结果：User 提交，Role 回滚
     * 数据：user_12
     */
    public void testNoTransactionNestedNestedException() {
        userService.createWithNested(12);
        roleService.createWithNestedException(12);
    }

   // JPA默认不支持嵌套事务
}
